// 先保留数组原型
const arrayProto = Array.prototype

export const arrayMethods = Object.create(arrayProto)

let methodsToPatch = [
  'push',
  'pop',
  'shift',
  'unshift',
  'splice',
  'reverse',
  'sort'
]

methodsToPatch.forEach((method) => {
  arrayMethods[method] = function (...args) {
    // 先保留原型方法执行结果
    const result = arrayProto[method].apply(this, args)

    // this 代表的是数据本身, __ob__ 拿到该数组的 Observer 实例
    const ob = this.__ob__

    let inserted

    switch (method) {
      case 'push':
      case 'unshift':
        inserted = args
        break
      case 'splice':
        inserted = args.slice(2) // 从第三个参数开始为新的数据, 前两个为 start 和 需要移除的数 deleteCount
      default:
        break
    }
    // 如果有新增的元素 inserted是一个数组 调用Observer实例的observeArray对数组每一项进行观测
    if (inserted) {
      ob.observeArray(inserted)
    }
    //数组派发更新 ob指的就是数组对应的Observer实例 我们在get的时候判断如果属性的值还是对象那么就在Observer实例的dep收集依赖 所以这里是一一对应的  可以直接更新
    ob.dep.notify()
    return result
  }
})
